{-
 This file is part of the Clafer to Alloy Translator (clafer2alloy).

 Copyright (C) 2010 Kacper Bak <http://gsd.uwaterloo.ca/kbak>

 clafer2alloy is free software: you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 clafer2alloy is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public License
 along with clafer2alloy. (See files COPYING and COPYING.LESSER.)  If not,
 see <http://www.gnu.org/licenses/>.
-}
{-
 This file is part of the Clafer to Alloy Translator (clafer2alloy).

 Copyright (C) 2010 Kacper Bak <http://gsd.uwaterloo.ca/kbak>

 clafer2alloy is free software: you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 clafer2alloy is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public License
 along with clafer2alloy. (See files COPYING and COPYING.LESSER.)  If not,
 see <http://www.gnu.org/licenses/>.
-}
import Control.Monad.State
import Data.Array.IArray

data Env = Env { n :: Int, l :: [Int], e1 :: Env1 } deriving Show

data Env1 = Env1 { x :: Int } deriving Show

run = runState process (Env 0 [] (Env1 0))


process = do
  modify (\e -> e { n = n e + 1, l = n e : l e })
  process1
  return 2
--  process2

process1 = do
  modify (\e -> e { n = n e + 1, l = n e : l e })
--  modify (\e -> e { e1 = execState process2 (e1 e) })
  f <- get
  let g = execState process2 (e1 f)
--  put f { e1 = g }
  modify id



process2 = modify (\e -> e { x = 5 })


run2 = runState (mapM process3 [1,2,3]) (Env 0 [] (Env1 0))

process3 m = modify (\e -> e { n = m, l = m : l e })

--run3 = runState process4 (Env 0 [1,2,3] (Env1 0))

-- process4 m = modify (\e -> e { n = m, l = m : l e })

--process4 m = liftM p5 getmodify (\e -> e { n = m, l = m : l e })

--p5 xs = tail xs ++ head xs


data AEnv = AEnv { lst :: [Int] } deriving Show

run4 = runState pr $ AEnv $ [1,2,3]

--myFn `liftM` get

pr = do
  a <- get
  mapM modif [0.. length $ lst a]

modif i = do
  (ps, us) <- liftM (fn i) get
--  u <- liftM (gt i) get
--  fun u
  modify (\e -> e { lst = ps ++ us })

gt i x = lst x !! i

fn i x = splitAt i $ lst x

-- int, array -> new elem
-- fun a i = a ! i + 1
